package org.emfjson.mongo.streams; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.mongodb.client.MongoCollection; import org.bson.Document; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.URIConverter.Saveable; import org.emfjson.jackson.JacksonOptions; import org.emfjson.jackson.module.EMFModule; import org.emfjson.mongo.MongoHandler; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Map; public class MongoOutputStream extends ByteArrayOutputStream implements Saveable { private final Map<?, ?> options; private final URI uri; private final MongoHandler handler; public MongoOutputStream(MongoHandler handler, URI uri, Map<?, ?> options) { this.handler = handler; this.uri = uri; this.options = options; } @Override public void saveResource(Resource resource) throws IOException { if (uri == null) { throw new IOException(); } final MongoCollection<Document> collection = handler.getCollection(uri); final String data = toJson(resource); if (data == null) { throw new IOException("Error during saving"); } final Document filter = new Document(MongoHandler.ID_FIELD, uri.segment(2)); if (collection.find(filter).limit(1).first() == null) { collection.insertOne(Document.parse(data)); } else { collection.findOneAndReplace(filter, Document.parse(data)); } } private String toJson(Resource resource) throws JsonProcessingException { final ObjectMapper mapper = new ObjectMapper(); final JacksonOptions jacksonOptions = JacksonOptions.from(options); mapper.registerModule(new EMFModule(resource.getResourceSet(), jacksonOptions)); final JsonNode contents = mapper.valueToTree(resource); final ObjectNode resourceNode = mapper.createObjectNode(); final String id = uri.segment(2); resourceNode.put(MongoHandler.ID_FIELD, id); resourceNode.put(MongoHandler.TYPE_FIELD, "resource"); resourceNode.set(MongoHandler.CONTENTS_FIELD, contents); return mapper.writeValueAsString(resourceNode); } }